#pragma once
#include "base/core/singleton.h"
#include "Common/ServerDefine.h"
#include "Common/NetPack/NetPack.h"
#include "Common/Utility/Service.h"
#include "Common/MessageDispatch/MessageDispatch.h"

class MasterService : public Service, public ManualSingleton<MasterService>
{
	friend class ManualSingleton<MasterService>;
	typedef std::unordered_map<uint32_t, ISession*>  SESSION_MAP;

protected:
	uint16_t       m_listenPort;
	char           m_listenIp[ADDRESS_IP_LENGTH];
	void*          m_listenHandle;

	uint64_t        m_syncStateTick;
	IMessageDispatch *m_pMessageDispatch;

	ServiceConnect    m_logServer;
	SESSION_MAP       m_zoneSessionMap;
	SESSION_MAP       m_loginSessionMap;
	ISession*         m_pWebSession;

public:
	virtual bool Init(Net* net, const char* configFile)override;
	virtual void UnInit()override;
	virtual bool Update(uint64_t tick)override;
	virtual bool Quit() override;
	virtual bool HandleConsoleCmd(const char* cmd)override;
	virtual IMessageDispatch *GetServiceMessageDispatch() override;
	bool _CheckQuittingComplete();

	bool AddZoneSession(uint32_t zid, ISession* session);
	bool AddLoginSession(uint32_t loginId, ISession* session);
	bool AddWebSession(uint32_t webId, ISession* session);

	bool SendDataToLogin(uint32_t loginId, uint16_t module, uint16_t cmd, ProtoBufBase* buf = nullptr);
	bool SendDataToAllLogin(uint16_t module, uint16_t cmd, ProtoBufBase* buf = nullptr);

	bool SendDataToZone(uint32_t zid, uint16_t module, uint16_t cmd, ProtoBufBase* buf = nullptr);
	bool SendDataToWeb(uint16_t cmd, ProtoBufBase* buf = nullptr);

protected:
	bool _LoadConfig(const char* config_file);
	bool _ListenAddress();

	bool _ProcessConnection();
	bool _SyncServiceState();

	static bool _OnAcceptServer(ISession* session, void* context);
	static bool _OnCloseServer(ISession* session, void* context, CloseFlag flag);
	static bool _OnConnectLogServer(ISession* session, void* context, bool success);

	MasterService();
	virtual ~MasterService()override;
};

#define g_MakesMasterService() (MasterService::Instance())
#define g_GetMasterService()   (MasterService::GetInstance())
#define g_DelMasterService()   (MasterService::Destroy())
